
#include "FragmentUnit.h"

Define_Module(FragmentUnit);

void FragmentUnit::initialize()
{
	this->m_FragmentSize = par("FragmentSize");
}

void FragmentUnit::handleMessage(cMessage* msg)
{
	NetworkPacket* packet = dynamic_cast<NetworkPacket*>(msg);

	if(packet != NULL)
	{
		this->FragmentAndSend(packet);
	}
	delete msg;
}

//fragments a packet and sends the fragments to the network interface
void FragmentUnit::FragmentAndSend(NetworkPacket* packet)
{
	while(packet->getByteLength() > this->m_FragmentSize)
	{
		NetworkPacket* packet_fragment = new NetworkPacket();
		packet_fragment->setByteLength(this->m_FragmentSize);
		int leftSize = packet->getByteLength() - this->m_FragmentSize;
		if(leftSize == 0)
		{
			this->updateLastFragment(packet_fragment, packet);
		}
		this->send(packet_fragment, "out");
		packet->setByteLength(leftSize);
	}
	if(packet->getByteLength() > 0)
	{
		this->updateLastFragment(packet, packet);
		send(packet->dup(), "out");
	}
}

//marks the last fragment and adds the receive time to it
void FragmentUnit::updateLastFragment(NetworkPacket* fragment, NetworkPacket* orig_packet)
{
	fragment->timeStamp = orig_packet->getArrivalTime();
	fragment->setKind(LAST_FRAGMENT);
}
